package com.yilin.xbr.common.interceptor;

import com.fasterxml.jackson.core.type.TypeReference;
import com.yilin.xbr.core.utils.JsonUtil;
import freemarker.template.utility.StringUtil;
import org.apache.commons.lang.StringUtils;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;

/**
 * APP请求解密过滤解析器
 */
public class HttpRequestWrapper extends HttpServletRequestWrapper {
    private Map<String, Object> bodyMap = new HashMap<>();

    // 请求是否加密
    private boolean isEncript;
    HttpRequestWrapper(HttpServletRequest request) throws IOException {
        super(request);
        try {
            request.setCharacterEncoding("UTF-8");
        } catch (UnsupportedEncodingException e1) {
            e1.printStackTrace();
        }
        String jsonData = request.getParameter("body");
        boolean upload = Boolean.parseBoolean(request.getHeader("upload")) ;
        if (!upload){
            if (StringUtils.isEmpty(jsonData)){//APP端默认取值方式变更：使用流传输
                BufferedReader br = request.getReader();
                String str;
                StringBuilder wholeStr = new StringBuilder();
                while((str = br.readLine()) != null){
                    wholeStr.append(str);
                }
                br.close();
                if (StringUtils.isNotEmpty(wholeStr.toString())){
                    Map<String,String> map = JsonUtil.serializeToObject(wholeStr.toString(), new TypeReference<Map<String, String>>() {});
                    jsonData=map.get("body");
                }
            }
        }
        String tokenID = request.getHeader("token");
        if (StringUtils.isNotEmpty(jsonData)) {
            try {
                if (StringUtils.isEmpty(jsonData) && request.getMethod().equals("POST")) {
                    System.out.print(request.getContentType());
                }
//                if (StringUtil.isNotEmpty(jsonData)) {
//                    jsonData = EncryptUtils.decrypt(jsonData, tokenID);
//                }
                this.bodyMap = JsonUtil.serializeToObject(jsonData, new TypeReference<Map<String, Object>>() {});
                setChildMap(bodyMap);
            } catch (Exception e) {
                e.printStackTrace();
            }
            isEncript = true;
        } else {
            isEncript = false;
        }
    }

    //MAP实体子类转换
    @SuppressWarnings("unchecked")
    private void setChildMap(Map<String, Object> paramMap){
        if (paramMap==null){
            return;
        }
        List<String> removeKeys = new ArrayList<>();
        List<String> removeKeys2 = new ArrayList<>();
        boolean hasMap = false;boolean hasList=false;
        for (String paramKey:paramMap.keySet()){
            if (paramMap.get(paramKey)==null){
            }else if (paramMap.get(paramKey) instanceof Map){
                removeKeys.add(paramKey);
                hasMap = true;
            }else if (paramMap.get(paramKey) instanceof ArrayList){
                removeKeys2.add(paramKey);
                hasList = true;
            }else if (paramMap.get(paramKey) instanceof Double){
                paramMap.put(paramKey, paramMap.get(paramKey));
            }else {
                paramMap.put(paramKey,String.valueOf(paramMap.get(paramKey)));
            }
        }
        for (String removeKey:removeKeys){
            Map<String, Object> childMap = (Map<String, Object>) paramMap.get(removeKey);
            for (String childKey:childMap.keySet()){
                paramMap.put(removeKey+"."+childKey,childMap.get(childKey));
            }
            paramMap.remove(removeKey);
        }
        for (String removeKey:removeKeys2){
            ArrayList<Object> list = (ArrayList<Object>) paramMap.get(removeKey);
            for (int i=0;i<list.size();i++){// "obh.list.0.sss"
                paramMap.put(removeKey+"["+i+"]",list.get(i));
            }
            paramMap.remove(removeKey);
        }

        if (hasMap||hasList){
            setChildMap(paramMap);
        }
    }

    //返回所有参数名
    @SuppressWarnings("rawtypes")
    @Override
    public Enumeration getParameterNames() {
        if (!isEncript) {
            return super.getParameterNames();
        }
        if (bodyMap==null){
            return null;
        }
        setChildMap(bodyMap);
        Vector<String> names = new Vector<>(this.bodyMap.keySet());
        return names.elements();
    }

    //获取所有参数值
    @Override
    public String[] getParameterValues(String name) {
        if (!isEncript) {
            return super.getParameterValues(name);
        }
        if (bodyMap == null || bodyMap.get(name)==null || StringUtils.isEmpty(bodyMap.get(name).toString())) {
            return null;
        }
        String data = bodyMap.get(name).toString();
        return new String[]{data};
    }

}
